package com.dream.service.recommender.web.parse.impl;

import com.dream.service.recommender.domain.model.PageInfo;
import com.dream.service.recommender.domain.model.UserInfo;
import com.dream.service.recommender.domain.request.FrontParam;
import com.dream.service.recommender.toolkits.utils.CheckUtil;
import com.dream.service.recommender.toolkits.utils.StringUtils;
import com.dream.service.recommender.web.model.Param;
import com.dream.service.recommender.web.parse.Parser;

import javax.servlet.http.HttpServletRequest;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zhiji on 2016/3/24.
 */
public class ParamParser implements Parser {

    private int maxExtraLen = 30;

    @Override
    public FrontParam parse(HttpServletRequest req) throws InvalidParameterException {
        FrontParam frontParam = new FrontParam();
        commonParser(req, frontParam);
        String rec_id = req.getParameter(Param.RECID);
        if (!StringUtils.isLong(rec_id)) {
            throw new InvalidParameterException("INVAID REC_ID");
        }
        frontParam.setRec_id(rec_id);
        String exp = req.getParameter(Param.EXP);
        if (!StringUtils.isEmpty(exp)) frontParam.setExp(exp);
        String cityId = req.getParameter("cityid");
        if(!StringUtils.isEmpty(cityId)){
            frontParam.setCityId(Integer.parseInt(cityId));
        }
        return frontParam;
    }

    @Override
    public FrontParam parseForOpen(HttpServletRequest req) throws InvalidParameterException {
        FrontParam frontParam = new FrontParam();
        commonParser(req, frontParam);
        String app_id = req.getParameter(Param.OpenParam.APPID);
        if (StringUtils.isEmpty(app_id)) {
            throw new InvalidParameterException("INVAID APPID");
        }
        String pos = req.getParameter(Param.OpenParam.POS);
        if (!StringUtils.isNumber(pos)) {
            throw new InvalidParameterException("INVAID POS");
        }
        // app_id + pos 映射一个Rec_id
        String rec_id = "200000";
        frontParam.setRec_id(rec_id);
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPage_size(2); // 坑位处固定放两个商品
        frontParam.setPage_info(pageInfo);
        String cityId = req.getParameter("cityid");
        if(!StringUtils.isEmpty(cityId)){
            frontParam.setCityId(Integer.parseInt(cityId));
        }
        return frontParam;
    }

    private void commonParser(HttpServletRequest req, FrontParam param) throws InvalidParameterException{
        String uuid = req.getParameter(Param.UUID);
        if (!CheckUtil.isvalidUUid(uuid, false)) {
            throw new InvalidParameterException("INVAID UUID");
        }
        String pin = req.getParameter(Param.PIN);
        if (!CheckUtil.isvalidPin(pin)) {
            throw new InvalidParameterException("INVAID PIN");
        }
        if (StringUtils.isEmpty(pin) && StringUtils.isEmpty(uuid)) {
            throw new InvalidParameterException("PIN AND UUID CAN'T ARE EMPTY AT THE SAME Time.");
        }
        if (!StringUtils.isEmpty(uuid) || !StringUtils.isEmpty(pin)) {
            UserInfo userInfo = new UserInfo();
            if (!StringUtils.isEmpty(uuid)) {
                userInfo.setUuid(uuid);
            }
            if (!StringUtils.isEmpty(pin)) {
                userInfo.setPin(pin);
            }
            param.setUser(userInfo);
        }
        String page_num = req.getParameter(Param.PAGENUM);
        if (!StringUtils.isEmpty(page_num) && !StringUtils.isLong(page_num)) {
            throw new InvalidParameterException("INVAID PAGE_NUM");
        }
        String page_size = req.getParameter(Param.PAGESIZE);
        if (!StringUtils.isEmpty(page_size) && !StringUtils.isLong(page_size)) {
            throw new InvalidParameterException("INVAID PAGE_SIZE");
        }
        PageInfo pageInfo = new PageInfo();
        if (!StringUtils.isEmpty(page_num) && !StringUtils.isEmpty(page_size)) {
            pageInfo.setPage_num(Integer.parseInt(page_num));
            pageInfo.setPage_size(Integer.parseInt(page_size));
        }
        param.setPage_info(pageInfo);
        String encode = req.getParameter(Param.ENCODE);
        param.setCharset(StringUtils.isEmpty(encode) ? Param.default_encode : encode);
        String extra_kv = req.getParameter(Param.EXTRA_KV);
        Map<String, String> extKVs = parseExtractKV(extra_kv);
        if(extKVs != null && extKVs.size() > 0) {
            param.setExtra_values(extKVs);//需要解析额外参数
        }
        String extra_info = req.getParameter(Param.EXTRA);
        if(!StringUtils.isEmpty(extra_info)) {
            param.setExtra_info(extra_info);//需要解析额外参数
        }
        String cid = req.getParameter(Param.CID);
        if (!StringUtils.isEmpty(cid)) {
            if (!StringUtils.isInteger(cid)) {
                throw new InvalidParameterException("INVAID CID");
            } else {
                param.setCid(Integer.parseInt(cid));
            }
        }
        String cid1 = req.getParameter(Param.CID1);
        if (!StringUtils.isEmpty(cid1)) {
            if (!StringUtils.isInteger(cid1)) {
                throw new InvalidParameterException("INVAID CID1");
            } else {
                param.setCid1(Integer.parseInt(cid1));
            }
        }
        String cid2 = req.getParameter(Param.CID2);
        if (!StringUtils.isEmpty(cid2)) {
            if (!StringUtils.isInteger(cid2)) {
                throw new InvalidParameterException("INVAID CID2");
            } else {
                param.setCid2(Integer.parseInt(cid2));
            }
        }
        String cid3 = req.getParameter(Param.CID3);
        if (!StringUtils.isEmpty(cid3)) {
            if (!StringUtils.isInteger(cid3)) {
                throw new InvalidParameterException("INVAID CID3");
            } else {
                param.setCid3(Integer.parseInt(cid3));
            }
        }
        String spu = req.getParameter(Param.SPU);
        if (!StringUtils.isEmpty(spu)) {
            if (!StringUtils.isLong(spu))
                throw new InvalidParameterException("INVAID SPU");
            else
                param.setSpu(Long.parseLong(spu));
        }
        String spus = req.getParameter(Param.SPUS);
        if (!StringUtils.isEmpty(spus)) {
            String[] ss = spus.split(",");
            List<Long> spuList = new ArrayList<Long>();
            for (String s : ss) {
                spuList.add(Long.parseLong(s));
            }
            param.setSpus(spuList);
        }
        String os = req.getParameter(Param.OS);
        if (!StringUtils.isEmpty(os)) {
            param.setOs(os);
        }
        String version = req.getParameter(Param.VER);
        if (!StringUtils.isEmpty(version)) {
            param.setVersion(version);
        }

        String cityId = req.getParameter("cityid");
        if(!StringUtils.isEmpty(cityId)){
            param.setCityId(Integer.parseInt(cityId));
        }
    }


    /**
     * 解析附加KV信息
     * @param extract
     * @return
     */
    private Map<String, String> parseExtractKV(String extract) {
        if (StringUtils.isEmpty(extract)) return null;
        Map<String,String> extractmap = new HashMap<String, String>();
        String extractarr[] = extract.split("\\$");
        int i = 0;
        for (String _extract : extractarr) {
            String[] kvs = _extract.split(":");
            if (kvs.length == 2 && validKV(kvs[0], kvs[1])) {//只是支持满足条件的key/value数据格式
                if ( i++ > maxExtraLen){
                    return extractmap;
                }
                extractmap.put(kvs[0], kvs[1]);
            }
        }
        return extractmap;
    }

    private boolean validKV(String key, String value) {
        return !StringUtils.isEmpty(key) && key.length() <= maxExtraLen && !StringUtils.isEmpty(value) && key.length() <= maxExtraLen;
    }
}
